﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using XemlUtilities.ISA.Ontology;
using XemlUtilities.DataSet;

namespace XemlUtilities.ISA.Protocol
{
    // base class : a mix between a factory (static methods) and a base class.
    public class ProtocolBase : IDisposable
    {
        #region constructors
        protected ProtocolBase()
        {
            Parameters = new List<Parameter>();
        }

        // has to be called at the end of derived class' constructor
        public void Register()
        {
            Protocols[this.Name] = this;
        }

        // Make this into a ProtocolFactory
        static ProtocolBase()
        {
            Protocols = new Dictionary<String, ProtocolBase>();
        }
        #endregion constructors

        // initiates all protocols. Only needs to run once during whole application 
        public static void Init(XemlDataSet xds, Guid xemlId, String connectionString)
        {
            if (ProtocolBase.xds == null)
            {
                ProtocolBase.xds = xds;
                ProtocolBase.xemlId = xemlId;
                ProtocolBase.connectionString = connectionString;

                // init all protocols - init'ing them, will put them into the Protocols dictionary.
                new Growth(xds);
                new MetaboliteExtraction();
                new MetaboliteIdentification();
                GcMs.InitProtocols(xemlId, connectionString);
                //MetaboliteExtraction.InitProtocols(xemlId, connectionString);
            }
        }

        #region members
        private static XemlDataSet xds;
        private static Guid xemlId;
        private static String connectionString;
        public string Name { get; set; }
        public string Type { get; set; }
        public string Description { get; set; }
        public Term AccessionNr { get; set; }
        private List<Parameter> Parameters { get; set; }

        static IDictionary<String, ProtocolBase> Protocols { get; set; } // list of all instantiated protocols: Name => instance
        #endregion members

        public static IEnumerable<ProtocolBase> GetProtocols()
        {
            return Protocols.Select(x => x.Value).ToList();
        }

        public static IDictionary<String, List<String>> GetOntologies()
        {
            // get a dict keyed on ontology name, with the used terms as values
            return GetProtocols().Where(x => x.AccessionNr != null)
                .GroupBy(x => x.AccessionNr.Ontology.Acronym)
                .ToDictionary(
                    x => x.Key,
                    z => z.Select(y => y.AccessionNr.AccessionNr).ToList()
            );
        }

        #region instance
        public virtual IEnumerable<Parameter> GetParameters()
        {
            return this.Parameters;
        }

        public virtual void AddParameter(Parameter param)
        {
            this.Parameters.Add(param);
        }
        #endregion instance

        public void Dispose() { }
    }
}
